package models

import "reflect"
import "strings"
import "encoding/json"
import "github.com/beego/beego/v2/client/orm"
import "beergo/lib/base/repository"
import "beergo/lib/mysql"
import "beergo/lib/tool"
import "github.com/beego/beego/v2/client/orm/hints"


func init() {
    //orm.RegisterModel(new(QuestionAnswers))
    orm.RegisterModelWithPrefix("check_", new(QuestionAnswers))
}

func (this *QuestionAnswers) GetReflect() reflect.Type {
    return reflect.TypeOf(QuestionAnswers{})
}
func (this QuestionAnswers) New() *QuestionAnswers {
    model := new(QuestionAnswers)
    model.SetCtx(this.GetCtx())
    //event.DispatchToMany("QuestionAnswersNew", model, this.GetCtx())
    this.Trigger("check.QuestionAnswersNew",model)
    return model
}
func (this *QuestionAnswers) Read(fields ...string) *QuestionAnswers {
    this.GetOrm().Read(this, fields...)
    return this
}
func (this *QuestionAnswers) Load(name string) *QuestionAnswers {
    this.GetOrm().LoadRelated(this, name)
    return this
}
func (this *QuestionAnswers) Save(fields ...string) (int64, error) {
    var id int64
    if this.Id == 0 {
        //event.DispatchToMany("check.BeforeQuestionAnswersCreate", this, this.GetCtx())
        this.Trigger("check.BeforeQuestionAnswersCreate",this)
        id, err := this.GetOrm().Insert(this)
        if err != nil {
            return id, err
        }
        //event.DispatchToMany("check.AfterQuestionAnswersCreate", this, this.GetCtx())
        this.Trigger("check.AfterQuestionAnswersCreate",this)
    } else {
        //event.DispatchToMany("check.BeforeQuestionAnswersUpdate", this, this.GetCtx())
        this.Trigger("check.BeforeQuestionAnswersUpdate",this)
        id, err := this.GetOrm().Update(this, fields...)
        if err != nil {
            return id, err
        }
        //event.DispatchToMany("check.AfterQuestionAnswersUpdate", this, this.GetCtx())
        this.Trigger("check.AfterQuestionAnswersUpdate",this)
    }
    return id, nil
}
func (this *QuestionAnswers) Delete() (int64, error) {
    //event.DispatchToMany("check.QuestionAnswersDelete", this, this.GetCtx())
    this.Trigger("check.QuestionAnswersDelete",this)
    return this.GetOrm().Delete(this)
}
func (this *QuestionAnswers) CreateFromObject(jsonData interface{}) *QuestionAnswers {
    tableByte, err := json.Marshal(jsonData)
    if err != nil {println(err.Error())}
    err = json.Unmarshal(tableByte, this)
    if err != nil {println(err.Error())}
    return this
}
func (this *QuestionAnswers) CreateFromString(jsonString string) *QuestionAnswers {
    err := json.Unmarshal([]byte(jsonString), this)
    if err != nil {println(err.Error())}
    return this
}
func (this *QuestionAnswers) ToString() string {
    ret, err := json.Marshal(this)
    if err != nil {println(err.Error())}
    return string(ret)
}
func (this *QuestionAnswers) FillList(name string, ids []int) orm.Ormer {
    o := orm.NewOrm()
    if this.Id == 0 {
        this.Save()
    }
    //__M2M_FILL__
    return o
}
func (this *QuestionAnswers) ToArray(fields string) map[string]interface{} {
    var data = make(map[string]interface{})
    if fields== "" || tool.HasSameWord(fields,"id") {
    data["id"] = this.Id
    }
    //__TO_ARRAY_FILL__
    if fields== "" ||  tool.HasSameWord(fields, "question") {
        if this.Question !=nil {
            this.Question.Read()
        }
        data["question"] = this.Question
    }
    if fields== "" ||  tool.HasSameWord(fields, "doctor") {
        if this.Doctor !=nil {
            this.Doctor.Read()
        }
        data["doctor"] = this.Doctor
    }
    if fields== "" ||  tool.HasSameWord(fields, "title") {
        data["title"] = this.Title
    }
    if fields== "" ||  tool.HasSameWord(fields, "content") {
        data["content"] = this.Content
    }
    if fields== "" ||  tool.HasSameWord(fields, "pics") {
        data["pics"] = this.Pics
    }
    if fields== "" ||  tool.HasSameWord(fields, "createAt") {
        data["createAt"] = this.CreateAt
    }
    if fields== "" ||  tool.HasSameWord(fields, "updateAt") {
        data["updateAt"] = this.UpdateAt
    }
    return data
}
func (this *QuestionAnswers) ToArrayEdit() map[string]interface{} {
    var data = make(map[string]interface{})
    data["id"] = this.Id
    //__EDIT_FILL__
    if this.Question == nil {
        data["question"] = ""
    }else {
        data["question"] = this.Question.Id
    }
    if this.Doctor == nil {
        data["doctor"] = ""
    }else {
        data["doctor"] = this.Doctor.Id
    }
    data["title"] = this.Title
    data["content"] = this.Content
    var tmpPics interface{}
    errPics:=json.Unmarshal([]byte(this.Pics),&tmpPics)
    if errPics != nil {
        tmpPics = ""
    }
    data["pics"] = tmpPics
    data["createAt"] = this.CreateAt
    data["updateAt"] = this.UpdateAt
    return data
}
func (this *QuestionAnswers) Scan(fields string,depth int,parent string) map[string]interface{} {
    var data = make(map[string]interface{})
    if fields== "" || tool.HasSameWord(fields, parent + "id") {
        data["id"] = this.Id
    }
    //__SCAN_FILL__
    if fields== "" || tool.HasSameWord(fields, parent + "question") {
        //this.GetOrm().LoadRelated(this,"question")
        if depth >0  && this.Question != nil {
        this.Question.Read()
            data["question"] = this.Question.Scan(fields,depth-1,"question.")
        }else {
            data["question"] = this.Question
        }
    }
    if fields== "" || tool.HasSameWord(fields, parent + "doctor") {
        //this.GetOrm().LoadRelated(this,"doctor")
        if depth >0  && this.Doctor != nil {
        this.Doctor.Read()
            data["doctor"] = this.Doctor.Scan(fields,depth-1,"doctor.")
        }else {
            data["doctor"] = this.Doctor
        }
    }
    if fields== "" ||  tool.HasSameWord(fields,  parent + "title") {
        data["title"] = this.Title
    }
    if fields== "" ||  tool.HasSameWord(fields,  parent + "content") {
        data["content"] = this.Content
    }
    var tmpPics interface{}
    if fields== "" ||  tool.HasSameWord(fields, parent + "pics") {
        errPics:=json.Unmarshal([]byte(this.Pics),&tmpPics)
        if errPics != nil {
            tmpPics = ""
        }
        data["pics"] = tmpPics
    }
    if fields== "" ||  tool.HasSameWord(fields,  parent + "createAt") {
        data["createAt"] = this.CreateAt
    }
    if fields== "" ||  tool.HasSameWord(fields,  parent + "updateAt") {
        data["updateAt"] = this.UpdateAt
    }
    return data
}


/***************************************
Repository
****************************************/
type QuestionAnswersRepository struct {
    repository.BaseRepository
}

func (this *QuestionAnswersRepository) GetQuerySetter() orm.QuerySeter {
    o := orm.NewOrm().QueryTable(QuestionAnswers{})
    if this.IsLoadRelation {
        o = o.RelatedSel()
    }
    return o
}
func (rep QuestionAnswersRepository) Find(id int) QuestionAnswers {
    filter := tool.DbCreateFilter()
    filter["Id"] = id
    return rep.FindOneBy(filter, nil)
}

func (rep QuestionAnswersRepository) FindOneBy(filters map[string]interface{}, orderbys []string) QuestionAnswers {
    var model QuestionAnswers
    qs := rep.GetQuerySetter()
    for key, item := range filters {
        qs = qs.Filter(key, item)
    }
    qs = qs.OrderBy(orderbys...)
    err := qs.Limit(1).One(&model)
    if err != nil {
        //todo
    }
    return model
}

func (rep QuestionAnswersRepository) FindBy(filters map[string]interface{}, orderbys []string, limit int, offset int) ([]QuestionAnswers, int64) {
    var models []QuestionAnswers
    qs := rep.GetQuerySetter()
    for key, item := range filters {
        qs = qs.Filter(key, item)
    }
    qs = qs.OrderBy(orderbys...)
    count, err := qs.Limit(limit).Offset(offset).All(&models)
    if err != nil {
        //todo
        print(count)
    }
    return models, count
}

func (rep QuestionAnswersRepository) CountBy(filters map[string]interface{}) int {
    qs := rep.GetQuerySetter()
    for key, item := range filters {
        qs = qs.Filter(key, item)
    }
    count, err := qs.Count()
    if err != nil {
        //todo
        print(count)
    }
    return tool.Int64ToInt(count)
}
func (rep QuestionAnswersRepository) FindAll(orderbys []string) ([]QuestionAnswers, int64) {
    var all []QuestionAnswers
    count, err := rep.GetQuerySetter().OrderBy(orderbys...).All(&all)
    if err != nil {
        //todo
        print(count)
    }
    return all, count
}

func (rep QuestionAnswersRepository) ListCount(filters map[string]interface{}) int {
    return rep.CountBy(filters)
}

func (rep QuestionAnswersRepository) ListAdmin(filters map[string]interface{}, orderbys []string, limit int, offset int) ([]QuestionAnswers, int64) {
    return rep.FindBy(filters, orderbys, limit, offset)
}

func (rep QuestionAnswersRepository) ListApi(filters map[string]interface{}, orderbys []string, limit int, offset int) ([]QuestionAnswers, int64) {
    return rep.FindBy(filters, orderbys, limit, offset)
}
func (rep QuestionAnswersRepository) ListCategory(Tree []map[string]interface{}, RootId int, startLevel int) []map[string]interface{} {
    where := tool.StringKeyMap{}
    if RootId == 0 {
        where["parent__isnull"] = true
    } else {
        where["parent"] = RootId
    }
    order := []string{"sort"}
    roots, _ := rep.FindBy(where, order, 0, 0)
    for _, root := range roots {
        prefix := ""
        if startLevel > 0 {
            prefix = "├"
        }
        name := reflect.ValueOf(root).FieldByName("Name").String()
        Tree = append(Tree, map[string]interface{}{
            "id":    root.Id,
            "value": prefix + strings.Repeat("╌╌", startLevel) + name,
        })
        rep.GetOrm().LoadRelated(&root, "Children")
        Tree = rep.ListCategory(Tree, root.Id, startLevel+1)
    }
    return Tree
}

/******************新增加的相关功能*************************/
func (rep QuestionAnswersRepository) Get(id int, builder *mysql.QueryBuilder) (*QuestionAnswers, error) {
    builder.Conditions["id"] = id
    return rep.GetOne(builder)
}

func (rep QuestionAnswersRepository) GetOne(builder *mysql.QueryBuilder) (*QuestionAnswers, error) {
    var model = new(QuestionAnswers)
    builder.Limit = 1
    builder.Page = 1
    qs := rep.PrepareQuery(builder)
    builder.MakeFields()
    fieldsOne:=rep.GetRelationStringOne(builder,&QuestionAnswers{})
    if len(fieldsOne)>0 {
        qs = qs.RelatedSel(fieldsOne...)
    }
    err := qs.One(model, builder.GetFields()...)
    if err != nil {
        return nil, err
    }

    fieldsMany:=rep.GetRelationStringMany(builder,&QuestionAnswers{})
    if len(fieldsMany) >0 {
        for _, f := range fieldsMany {
            _,err:=rep.GetOrm().LoadRelated(model,f)
            if err !=nil {
                //return nil, err
            }
        }
    }
    return model, nil
}
func (rep QuestionAnswersRepository) GetList(builder *mysql.QueryBuilder) ([]*QuestionAnswers, error) {
    //ormer:= orm.NewOrm()
    o := rep.PrepareQuery(builder)
    builder.MakeFields()
    fieldsOne:=rep.GetRelationStringOne(builder,&QuestionAnswers{})
    if len(fieldsOne)>0 {
        o = o.RelatedSel(fieldsOne...)
    }
    var data []*QuestionAnswers
    _, err := o.All(&data, builder.GetFields()...)
    if err != nil {
        return nil, err
    }
    total, err := rep.Count(builder)
    if err != nil {
        return nil, err
    }
    builder.Total = total
    fieldsMany:=rep.GetRelationStringMany(builder,&QuestionAnswers{})
    if len(fieldsMany) >0 {
        for _, f := range fieldsMany {
            for _, row := range data {
                _,err:=rep.GetOrm().LoadRelated(row,f)
                if err !=nil {
                    //return nil, err
                }
            }
        }
    }
    return data, nil
}

func (rep QuestionAnswersRepository) Count(builder *mysql.QueryBuilder) (int64, error) {
    qs := rep.PrepareQuery(builder)
    count, err := qs.Count()
    if err != nil {
        return 0, err
    }
    return count, nil
}

func (rep QuestionAnswersRepository) PrepareQuery(builder *mysql.QueryBuilder) orm.QuerySeter {
    o := orm.NewOrm().QueryTable(QuestionAnswers{})
    for key, item := range builder.GetFilter() {
        o = o.Filter(key, item)
    }
    for key, item := range builder.GetExclude() {
        o = o.Exclude(key, item)
    }
    searchConf := rep.CreateSearch(builder)
    if searchConf !=nil {
        o = o.SetCond(searchConf)
    }
    builder.MakeFields()
    o = o.OrderBy(builder.GetOrder()...).
        Limit(builder.GetLimit()).
        Offset(builder.GetOffset())
    return o
}

func (rep QuestionAnswersRepository) neverUsedInRep(){
    c:=hints.Hint{}
    print(&c)
}
